﻿/*=============================================================================
* File Name : Math.h                             Ver : 1.00  Date : 2009-3-15
*
* Description :
*
*       数学基本計算　ヘッダ
*
* Author : 土田　悠貴.
*============================================================================*/
#ifndef _MYMATH_H_
#define _MYMATH_H_

namespace tglib
{

/**
 * @brief 数学基本計算クラス．
 */
class Math
{
public:
	/**< 円周率 */
	static const float PI;

	/*===========================================================================*/
	/**
	 * 絶対値を求める．
	 *
	 * [template] T.
	 * @param [in] a  絶対値にしたい数値 ．
	 * @return   絶対値．
	 */
	template<typename T>
	static T ABS( T a )
	{
		return ( ( (a) < (0) ) ? -(a) : (a) );
	}

	/*===========================================================================*/
	/**
	 * 小さい方の値を求める．
	 *
	 * [template] T.
	 * @param [in] a  比べたい値 ．
	 * @param [in] b  比べたい値 ．
	 * @return   小さい値．
	 */
	template<typename T>
	static T MIN( T a, T b )
	{
		return ( ( (a) < (b) ) ? (a) : (b) );
	}

	/*===========================================================================*/
	/**
	 * 大きい方の値を求める．
	 *
	 * [template] T.
	 * @param [in] a  比べたい値 ．
	 * @param [in] b  比べたい値 ．
	 * @return   大きい値．
	 */
	template<typename T>
	static T MAX( T a, T b )
	{
		return ( ( (a) > (b) ) ? (a) : (b) );
	}

	/*===========================================================================*/
	/**
	 *  正なら１，負なら－１，ゼロなら０を返す．
	 *
	 * [template] T.
	 * @param [in] a  調べたい値 ．
	 * @return   正なら１，負なら－１，ゼロなら０．
	 */
	template<typename T>
	static int ZSGN( T a )
	{
		return ( ( (a) < 0 ) ? -1 : (a) > 0 ? 1 : 0 );
	}

	/*===========================================================================*/
	/**
	 *  ａが正またはゼロなら１，負なら－１なら０を返す．
	 *
	 * [template] T.
	 * @param [in] a  調べたい値 ．
	 * @return   ａが正またはゼロなら１，負なら－１．
	 */
	template<typename T>
	static int SGN( T a )
	{
		return ( ( (a) < 0 ) ? -1 : 1 );
	}

	/*===========================================================================*/
	/**
	 * 二乗をする．
	 *
	 * [template] T.
	 * @param [in] a  二乗したい値 ．
	 * @return   二乗した値．
	 */
	template<typename T>
	static T SQR( T a )
	{
		return ( a * a );
	}

	/*===========================================================================*/
	/**
	 * ｖをｌからｈの値に留める．
	 *
	 * [template] T.
	 * @param [in] v  補間したい値 ．
	 * @param [in] l  最少値 ．
	 * @param [in] h  最大値 ．
	 * @return   補間した値．
	 */
	template<typename T>
	static T CLAMP( T v, T l, T h )
	{
		return MAX( l, MIN( v, h ) );
	}

	/*===========================================================================*/
	/**
	 * 線形補間をする(aは0.0～1.0)．
	 *
	 * @param [in] a  補間したい値(0.0～1.0) ．
	 * @param [in] l  最少値 ．
	 * @param [in] h  最大値 ．
	 * @return   補間した値．
	 */
	static float LERP( float a, float l, float h );

	/*===========================================================================*/
	/**
	 * ２次補間する(aは0.0～1.0)．
	 *
	 * @param [in] a  補間したい値(0.0～1.0) ．
	 * @param [in] v1  補間値1 ．
	 * @param [in] v2  補間値2 ．
	 * @param [in] v3  補間値3 ．
	 * @return   補間した値．
	 */
	static float QUADRATIC( float a, float v1, float v2, float v3 );

	/*===========================================================================*/
	/**
	 * 配列の要素数を求める．
	 *
	 * @param [in] a  補間したい値(0.0～1.0) ．
	 * @return   配列の要素数を返す．
	 */
	template<typename T>
	static int ARRAY_LENGTH( T a )
	{
		return ( sizeof( a ) / sizeof( a[0] ) );
	}

	/*===========================================================================*/
	/**
	 * 乱数の初期化．
	 */
	static void Randamize();

	/*===========================================================================*/
	/**
	 * 乱数値を求める．
	 *
	 * @param [in] min  乱数の最小値 ．
	 * @param [in] max  乱数の最大値．
	 * @return   求めた乱数を返す．
	 */
	static int Rand( int min, int max );

	/*===========================================================================*/
	/**
	 * 浮動小数点の乱数値を求める．
	 *
	 * @param [in] min  乱数の最小値 ．
	 * @param [in] max  乱数の最大値．
	 * @return   求めた乱数を返す．
	 */
	static float Randf( float min, float max );

	/*===========================================================================*/
	/**
	 * 平方根を求める．
	 *
	 * @param [in] min  平方根を求めたい値 ．
	 * @return   求めた平方根．
	 */
	static float Sqrt( float x );

	/*===========================================================================*/
	/**
	 * 正弦を求める．
	 *
	 * @param [in] deg  角度 ．
	 * @return   正弦．
	 */
	static float Sin( float deg );

	/*===========================================================================*/
	/**
	 * 余弦を求める．
	 *
	 * @param [in] deg  角度 ．
	 * @return   余弦．
	 */
	static float Cos( float deg );

	/*===========================================================================*/
	/**
	 * 正接を求める．
	 *
	 * @param [in] deg  角度 ．
	 * @return   正接．
	 */
	static float Tan( float deg );

	/*===========================================================================*/
	/**
	 * 逆正弦を求める．
	 *
	 * @param [in] deg  角度 ．
	 * @return   逆正弦．
	 */
	static float Asin( float deg );

	/*===========================================================================*/
	/**
	 * 逆余弦を求める．
	 *
	 * @param [in] deg  角度 ．
	 * @return   逆余弦．
	 */
	static float Acos( float deg );

	/*===========================================================================*/
	/**
	 * 逆正接を求める．
	 *
	 * @param [in] deg  角度 ．
	 * @return   逆正接．
	 */
	static float Atan( float deg1, float deg2 );

	/*===========================================================================*/
	/**
	 * ラジアンを求める．
	 *
	 * @param [in] deg  角度 ．
	 * @return   ラジアン．
	 */
	static float DegToRad( float deg );

	/*===========================================================================*/
	/**
	 * 角度を求める．
	 *
	 * @param [in] rad  ラジアン ．
	 * @return   角度．
	 */
	static float RadToDeg( float rad );

	/*===========================================================================*/
	/**
	 * 正規化した角度を求める．
	 *
	 * @param [in] rad  角度 ．
	 * @return   正規化した角度．
	 */
	static float DegreeNormalize( float rad );
};

} // namespace tglib

#endif

/*========= End of File =====================================================*/
